<template>
  <div class="fx-radio-group" :class="{'button-group':isButton}">
    <slot></slot>
  </div>
</template>

<script lang="ts">
import {
  computed,
  defineComponent,
  inject,
  onBeforeUnmount,
  onMounted,
  PropType,
  provide,
  ref,
  SetupContext,
  watch
} from 'vue'
import mitt, { Emitter } from 'mitt'
import { ComponentSize, componentSizeArr } from '@/base/types'
import { useIsDefaultSlotName } from '@/base/hooks'

export type RadioModelValue = number | string | { [key: string]: unknown } | boolean

interface RadioGroup {
  modelValue: RadioModelValue;
  size: ComponentSize;
  disabled: boolean;
  valueKey: string;
}

export default defineComponent({
  name: 'FRadioGroup',
  props: {
    // v-model
    modelValue: {
      type: [Number, String, Object] as PropType<RadioModelValue>,
      required: true
    },
    // 禁用
    disabled: {
      type: Boolean as PropType<boolean>,
      default: false
    },
    // 大小
    size: {
      type: String as PropType<ComponentSize>,
      default: 'default',
      validator (val: ComponentSize): boolean {
        return componentSizeArr.includes(val)
      }
    },
    // 传入对象 绑定的key值
    valueKey: {
      type: String as PropType<string>,
      default: null
    }
  },
  emits: ['update:modelValue', 'change'],
  setup (props: RadioGroup, ctx: SetupContext) {
    // 监听事件初始化
    const radioGroupMitt: Emitter = mitt()
    // 当前选中
    const radioGroupValue = ref<RadioModelValue>(props.modelValue)
    // 判断是否是按钮模式
    const isButton = useIsDefaultSlotName('FRadioButton')
    // 接收formItem mitt 监听器
    const formItemMitt = inject<Emitter['emit'] | undefined>('formItemMitt', undefined)

    // 处理子级返回的选中值
    const handleRadioGroupItem = (val: RadioModelValue | undefined): void => {
      if (!val) return
      radioGroupValue.value = val
      ctx.emit('change', val)
    }
    // 下发 radioGroup 当前选中
    provide('radioGroupValue', computed(() => radioGroupValue.value))
    // 下发 radioGroup 禁用
    provide('radioGroupDisabled', props.disabled)
    // 下发 radioGroup 对象 选择key
    provide('radioGroupValueKay', props.valueKey)
    // 下发 radioGroup 大小
    provide('radioGroupSize', computed(() => props.size))
    // 下发mitt给子级
    provide<Emitter['emit']>('radioGroupMittEmit', radioGroupMitt.emit)

    watch(() => props.modelValue, (val: RadioModelValue) => {
      radioGroupValue.value = val
    })
    watch(radioGroupValue, (val: RadioModelValue) => {
      // 发送当前的数据给formItem
      if (formItemMitt) formItemMitt('formItemValue', val)
      ctx.emit('update:modelValue', val)
      ctx.emit('change', val)
    })

    onMounted(() => {
      radioGroupMitt.on<string | undefined>('radioGroupClick', handleRadioGroupItem)
      // 发送当前的数据给formItem
      if (formItemMitt) formItemMitt('formItemValue', radioGroupValue.value)
    })

    onBeforeUnmount(() => {
      radioGroupMitt.off('radioGroupClick', handleRadioGroupItem)
    })

    return {
      isButton
    }
  }
})
</script>
